#include <stdio.h>
#include <stdlib.h>

#define NO_WAYS 10
#define MAX_RET 100
//#define DEBUG

#ifdef DEBUG
	#define VISUALISE {\
	int l1 = 0, l2 = 0;\
	printf("%d-%d\n", s->x, s->y);\
	printf("start:%d-%d moves:%d returns:%d\n", s->full_way[0].x, s->full_way[0].y, s->k, s->ret_count);\
	for (l1 = 0; l1 < s->m; l1++)\
	{\
		for (l2 = 0; l2 < s->n; l2 ++)\
			if (s->a[l1][l2] == 0) printf(". "); else printf("# ");\
		printf("\n");\
	}\
	getc(stdin);}
#else
	#define VISUALISE
#endif

struct position
{
	int x, y;
};

/* ways counterclockwise */
const struct position cc_ways[8] = {{-1, 2}, {-2, -1}, {-2, 1}, {-1, -2}, 
					{1, -2}, {2, -1}, {2, 1}, {1, 2}};

struct state
{
	int m, n;/* board size: m - strings, n - columns */
	int** a;/* board */
	struct position way[8];
	int x, y;/* position */
	struct position* full_way;
	int k; /* points in full way */
	int ret_count;
};

struct state* state_initialize(int m, int n);
void state_destroy(struct state* s);
void knights_tour(struct state* s);
int ways(int x, int y, struct state* s);
int on_board(int x, int y, struct state* s);
int way_print(struct state* s);
void fill_ways(struct state* s, int start, int direction);

int main()
{
	int m = 0, n = 0;/* board size */
	int i = 0, j = 0;
	int bad = 0, good = 0;
	scanf("%d%d", &m, &n);
	for (i = 0; i < m; i++)
		for (j = 0; j < n; j++)
		{
			int k = 0;
			int b = 0;
			if ((m*n) % 2 == 1 && (i+j) % 2 == 1) /* if an odd number of squares on board */
			{
				printf("Way from point %d %d is not exist\n", i, j);
				good++;
				continue;
			}
			for (k = 0; k < 16 && b == 0; k++)
			{
				struct state* s = state_initialize(m, n);
				s->x = i;
				s->y = j;
				fill_ways(s, k % 8, k/8);
				knights_tour(s);
				if (s->ret_count < MAX_RET) 
				{
					/* printf("%d %d\n", i, j); */
					way_print(s);
					good++;
					b = 1;
				}
				state_destroy(s);
			}
			if (b == 0) 
			{
				bad++;
				printf("I cant find way from point %d %d (((\n", i, j);
			}
		}
	printf("Ways founded: %d\nCant found: %d\n", good, bad);
	return 0;
}

struct state* state_initialize(int m, int n)
{
	int i = 0;
	struct state* new_state = (struct state*) calloc(1, sizeof(struct state));
	new_state->m = m;
	new_state->n = n;
	new_state->a = (int**) calloc(m, sizeof(int*));
	for (i = 0; i < m; i++)
		new_state->a[i] = (int*) calloc(n, sizeof(int));
	new_state->x = -1;
	new_state->y = -1;
	new_state->full_way = (struct position*) calloc(m*n, sizeof(struct position));
	new_state->k = 0;
	return new_state;
}

void fill_ways(struct state* s, int start, int direction)
{
	int i = 0;
	if (direction == 0) /* counterclockwise */
	{
		for (i = 0; i < 8; i++)
			s->way[(i+start) % 8] = cc_ways[i];
	}
	else /* clockwise */
	{
		for (i = 0; i < 8; i++)
			s->way[(8+start-i) % 8] = cc_ways[i];
	}
}

void state_destroy(struct state* s)
{
	int i = 0;
	for (i = 0; i < s->m; i++) free(s->a[i]);
	free(s->a);
	free(s->full_way);
	free(s);
}

void knights_tour(struct state* s)
{
	int bad_way[8] = {0}; /* all ways is good */	
	if (s->ret_count >= MAX_RET) return; /* so long we cant find way */ 	
	s->a[s->x][s->y] = 1;
	s->full_way[s->k].x = s->x;
	s->full_way[s->k].y = s->y;
	(s->k)++;
	/* VISUALISATION FOR DEBUGGING */
	VISUALISE;
	/* END OF DEBUG VISUALISATION */	
	if (s->k == s->m * s->n) return; /* we found way */ 
	while (1) /* exit if no ways */
	{		
		/* find way */
		int way_count = NO_WAYS;/* 10 == no ways */
		int index = 0, i = 0;
		for (i = 0; i < 8; i++)
		{
			if (!bad_way[i]) 
			{
				int w = ways(s->x + s->way[i].x, s->y + s->way[i].y, s);
				if (w == -1) bad_way[i] == 1;
				else if (w < way_count || way_count == 0)
				{
					way_count = w;
					index = i;	
				}
			}
		}
		if (way_count == NO_WAYS) break;/* exit from while */
		bad_way[index] = 1;
		/* go to the chosen point */
		s->x += s->way[index].x;
		s->y += s->way[index].y;
		knights_tour(s);
		if (s->k == s->m * s->n) return; /* we found way */ 
		s->x -= s->way[index].x;
		s->y -= s->way[index].y;
	}
	(s->k)--;
	s->a[s->x][s->y] = 0;
	(s->ret_count)++;
}

int ways(int x, int y, struct state* s)
{
	int i = 0;
	int w = 0;
	if (!on_board(x, y, s)) return -1;/* bad way */
	if (s->a[x][y] == 1) return -1;/* bad way */
	for (i = 0; i < 8; i++)
	{	
		if (on_board(x+s->way[i].x, y+s->way[i].y, s))
			if (s->a[x+s->way[i].x][y+s->way[i].y] == 0) w++;
	}
	return w;
}

int on_board(int x, int y, struct state* s)
{
	if (x < s->m && x >= 0 && y < s->n && y >= 0) return 1;
	return 0;
}

int way_print(struct state* s)
{
	int i = 0;
	printf("Way from point %d %d:\n", s->full_way[0].x, s->full_way[0].y);
	if (s->k != s->m * s->n) printf("Cant find way for starting point: %d-%d", s->full_way[0].x, s->full_way[0].y);
	for (i = 0; i < s->k; i++)
		printf("%d-%d ", s->full_way[i].x, s->full_way[i].y);
	printf("\n");
}
